'use strict';

/**
 * 数据库模型超类
 */
class BaseModel {
  
  constructor(_tableName, _key) {
    this.tableName = _tableName;
    this.key = _key;
  }
  
  transformation_DBEntitys(_Entitys) {
    if (_Entitys && _Entitys.length > 0) {
      const entityList = [];
      for (const dbentity of _Entitys) {
        let entity = new this.entity();
        entity = this.transformation_Entity(dbentity);
        entityList.push(entity);
      }
      return entityList;
    }
    return [];
  }

  /**
   * 将符合规范的实体对象转换为数据库对象
   * @param {object} _Entity 实体对象
   */
  transformation_DBEntity(_Entity) {
    // console.log('需要转换的数据：', _Entity);
    const _DBEntity = {};
    // 获取实体对象的所有属性，得到属性数组
    const names = Object.getOwnPropertyNames(_Entity);
    // 将模型定义的列名数组提取出来，为解决多穿参数，导致数据库报错
    const thisEntityNames = Object.getOwnPropertyNames(new this.entity());
    // 遍历数组
    for (const name of names) {
      const isHave = thisEntityNames.find(item => {
        return name == item;
      });
      if (isHave) {
        // 将传入属性转为符合规范的数据库对象属性名称
        const dbname = this.parseDBName(name);
        const nameValue = Object.getOwnPropertyDescriptors(_Entity)[name];
        if (nameValue && nameValue.value != null && nameValue.value != undefined) {
          _DBEntity[dbname] = Object.getOwnPropertyDescriptors(_Entity)[name].value;
        }
      }
    }
    return _DBEntity;
  }

  transformation_Entity(_DBEntity) {
    const _Entity = {};
    // 获取数据库对象的所有属性，得到属性数组
    const dbnames = Object.getOwnPropertyNames(_DBEntity);
    // 遍历数组
    for (const dbname of dbnames) {
      // 将传入的数据库列名转为符合规范的实体对象属性名称
      const name = this.parseEName(dbname);
      const dbnameVlue = Object.getOwnPropertyDescriptors(_DBEntity)[dbname];
      if (dbnameVlue && dbnameVlue.value != null &&  dbnameVlue.value != undefined) {
        _Entity[name] = dbnameVlue.value;
      }
    }
    return _Entity;
  }
  /**
   * 转换为符合规范的数据库列名称
   * @param {string} name 属性名称
   */
  parseDBName(name) {
    // 查找大写字母
    const keys = name.match(/[A-Z]/g);
    if (keys && keys.length > 0) {
      for (const key of keys) {
        name = name.replace(key, '_' + key.toLowerCase());
      }
    }
    return name;
  }
  
  /**
   * 转换符合规范的实体对象属性名称
   * @param {string} dbname 数据库列名
   */
  parseEName(dbname) {
    // 查找 _ + 字母
    const keys = dbname.match(/_[a-z]/g);
    if (keys && keys.length > 0) {
      for (const key of keys) {
        dbname = dbname.replace(key, key.replace('_', '').toUpperCase());
      }
    }
    return dbname;
  }

  // 插入信息
  async insert(app, entity) {
    const dbentity = this.transformation_DBEntity(entity);
    return await app.mysql.insert(this.tableName, dbentity);
  }

  async insert_transaction(conn, entity) {
    const dbentity = this.transformation_DBEntity(entity);
    return await conn.insert(this.tableName, dbentity);
  }

  async insertBatch(app, entitys) {
    const dbentitys = [];
    for (const entity of entitys) {
      const dbentity = this.transformation_DBEntity(entity);
      dbentitys.push(dbentity);
    }
    return await app.mysql.insert(this.tableName, dbentitys);
  }

  async insertBatch_transaction(conn, entitys) {
    const dbentitys = [];
    for (const entity of entitys) {
      const dbentity = this.transformation_DBEntity(entity);
      dbentitys.push(dbentity);
    }
    return await conn.insert(this.tableName, dbentitys);
  }

  // 根据ID 删除信息
  async deleteById(app, key) {
    const options = '{"' + this.key + '":"' + key + '"}';
    return await app.mysql.delete(this.tableName, JSON.parse(options));
  }

  async deleteById_transaction(conn, key) {
    const options = '{"' + this.key + '":"' + key + '"}';
    return await conn.delete(this.tableName, JSON.parse(options));
  }


  // 根据ID 更新信息
  async updateById(app, entity) {
    const dbentity = this.transformation_DBEntity(entity);
    return await app.mysql.update(this.tableName, dbentity);
  }

  async updateById_transaction(conn, entity) {
    const dbentity = this.transformation_DBEntity(entity);
    return await conn.update(this.tableName, dbentity);
  }

  // 根据ID 查询信息
  async findOneById(app, key) {
    const options = {};
    options[this.key] = key;
    
    let entity = new this.entity();
    // 查询数据
    const dbentity = await app.mysql.get(this.tableName, options);
    // console.log('返回数据：', dbentity);
    // 将数据库数据，转换为实体对象
    if (dbentity) {
      entity = this.transformation_Entity(dbentity);
      return entity;
    }
    return null;
  }

  /**
   * 根据单位编号获取，本单及下级单位编号，以及本单位所属地区及下级所属区域
   * @param {object} app app对象
   * @param {string} branchCode 当前用户所在单位编号
   * @param {int} resultType 返回类型 1 返回单位编号 0 返回地区编号
   * @param {int} isContainChildNode 是否返回子节点数据 0 不返回 1 返回
   */
  async getUserAreaCodesOrBranchCodeByBranchCode(app, branchCode, resultType, isContainChildNode) {
    const codes = await app.mysql.query(`select getUserAreaCodesOrBranchCodeByBranchCode('${branchCode}',${resultType},${isContainChildNode}) as codes`);
    app.logger.debug('---------------获取到编号：', codes);
    if (codes && codes.length > 0) {
      return codes[0].codes;
    }
    return [];
  }

}

module.exports = BaseModel;
